# -*- coding: utf-8 -*-

class ClassOne(object):
    id = 0
    name = ""
    age = 0
    data = {}

    # __init__是在类实例创建之后调用，而__new__方法正是创建这个类实例的方法。
    def __init__(self, id):
        print("ClassOne.__init__")
        self.id = id

    # __new__必须要有返回值，返回实例化出来的实例，这点在自己实现__new__时要特别注意，可以return父类__new__出来的实例，或者直接是object的__new__出来的实例
    # __init__有一个参数self，就是这个__new__返回的实例，__init__在__new__的基础上可以完成一些其它初始化的动作，__init__不需要返回值
    # 若__new__没有正确返回当前类cls的实例，那__init__是不会被调用的，即使是父类的实例也不行
    # __new__方法在类定义中不是必须写的，如果没定义，默认会调用object.__new__去创建一个对象。如果定义了，就是override
    # 聪明的读者可能想到，既然__new__可以custom对象的创建，那我在这里做一下手脚，每次创建对象都返回同一个，那不就是单例模式了吗？
    def __new__(cls, id):
        print("ClassOne.__new__")
        cls.id = id
        return super(ClassOne, cls).__new__(cls)

    def add_age(self):
        self.age = self.age + 1

    def __str__(self):
        return "ClassOne[id=" + str(self.id) + ",name=" + self.name + ",age=" + str(self.age) + "]"

    def __call__(self, *args, **kwargs):
        return "ClassOne is called"

    def __lt__(self, other):
        return self.id > other.id

    #对象被销毁时会调用该方法
    def __del__(self):
        print("del ClassOne id=" + str(self))

    #使用inst[key]=value时调用
    def __setitem__(self, key, value):
        self.data[key] = value

    #使用inst[key]时调用
    def __getitem__(self, key):
        return self.data[key]

    def __cmp__(self, other):
        return self.id - other.id

    # *args可以当作可容纳多个变量组成的list
    # **kwargs可以当作容纳多个key和value的dictionary
    def set_prop(self, *args, **kwargs):
        self.id = args[0]
        self.name = kwargs["name"]
        self.age = kwargs["age"]


if __name__ == "__main__":
    co1 = ClassOne(id=1)
    print(co1)
    print(co1())
    co1.add_age()
    print(co1)
    co1.set_prop(2, name="hello", age=10)
    print(co1)

    co2 = ClassOne(id=3)
    print(co1.__lt__(co2))

    key = "name"
    co2.__setitem__(key, "hello")
    print(co2.__getitem__(key))
    co2[key] = "hello world"
    print(co2[key])

    del co1
    del co2
